package com.xiguthings.waka.web.controller.wechat;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiguthings.waka.po.User;
import com.xiguthings.waka.publicUtils.StringUtils;
import com.xiguthings.waka.service.user.IUserService;
import com.xiguthings.waka.web.controller.base.AbstractController;
import com.xiguthings.waka.web.controller.base.ResponseEntity;
import com.xiguthings.waka.web.controller.wechat.vo.SnsapiEntity;
import com.xiguthings.waka.web.controller.wechat.wx.*;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

@ApiIgnore
@Controller
@RequestMapping("/wechat")
public class WechatController extends AbstractController {

    @Resource
    private IUserService userService;

    @Resource
    private WxService wxService;

    // private static String TOKEN = "westv123";
    private Map<String, JSONObject> msgMap = new Hashtable<>();// 微信发送来的消息，去重用的集合
    private Map<String, SnsapiEntity> openidMap = new HashMap<>();// 根据向微信拉取微信用户信息后，缓存用户信息的集合
    Logger log = Logger.getLogger(WechatController.class);


    /**
     * 入口鉴别是来自哪里的用户 微信
     *
     * @param code
     * @param state
     * @param scope
     * @throws Exception
     */
    private void whereComeFrom(String code, String state, String scope) throws Exception {

        wx_redirect_handle(code, state, scope);

    }


    /**
     * 所有从微信app进入浏览器都需要通过次方法获取当前用户信息<br>
     * 获取当前访问网页的用户,拉取到的用户信息和根据openid查询到的用户信息
     *
     * @param code
     * @param state
     * @param scope
     * @return
     * @throws Exception
     */
    private void wx_redirect_handle(String code, String state, String scope) throws Exception {
        /*
         * { "openid":" OPENID",
         *
         * "nickname": NICKNAME,
         *
         * "sex":"1",
         *
         * "province":"PROVINCE"
         *
         * "city":"CITY",
         *
         * "country":"COUNTRY",
         *
         * "headimgurl": "http://wx.qlogo.cn/mmopen/
         * g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ
         *
         * 4eMsv84eavHiaiceqxibJxCfHe/46",
         *
         * "privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
         *
         * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
         *
         * }
         */

        SnsapiEntity snsapiEntity = null;
        User user = null;

        if (StringUtils.isNotBlank(code)) {
            if ((snsapiEntity = openidMap.get(code)) == null) {
                // ----------获取正在访问的用户，并缓存
                JSONObject jobj = WxConnExec.getAccess_tokenByCode(code);
                snsapiEntity = JSON.toJavaObject(JSON.parseObject(jobj.toString()), SnsapiEntity.class);
                String openid = snsapiEntity.getOpenid();
                JSONObject userInfo = null;
                if (scope != null && scope.equals(SNSAPI_USERINFO)) {
                    userInfo = WxConnExec.getUserInfo(openid);
                    snsapiEntity.setScope(scope);
                    snsapiEntity.setNickname(userInfo.getString("nickname"));
                    snsapiEntity.setSex(userInfo.getString("sex"));
                    snsapiEntity.setProvince(userInfo.getString("province"));
                    snsapiEntity.setCity(userInfo.getString("city"));
                    snsapiEntity.setCountry(userInfo.getString("country"));
                    snsapiEntity.setHeadimgurl(userInfo.getString("headimgurl"));
                    snsapiEntity.setPrivilege(userInfo.getString("privilege"));
                    snsapiEntity.setUnionid(userInfo.getString("unionid"));
                }
                openidMap.put(code, snsapiEntity);
            }

            String openid = snsapiEntity.getOpenid();
            user = userService.selectByOpenid(openid);
            if (user == null) {// 如果数据库中没有该用户，则新建立一条用户信息
                user = new User();
                openid = snsapiEntity.getOpenid();
                user.setOpenid(openid);
                userService.insert(user);
            }
        }

        HttpSession session = super.getSession();
        session.setAttribute(SESSION_CRN_USER, user);
        session.setAttribute(SESSION_CRUN_SNSAPIENTITY, snsapiEntity);

    }

    /**
     * 微信消息入口
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @return
     * @throws IOException
     */
    @ResponseBody
    @RequestMapping("/check")
    public String check(String signature, String timestamp, String nonce, String echostr, HttpServletRequest request,
                        HttpServletResponse response) throws IOException {
        // ServletOutputStream out = response.getOutputStream();
        Logger log = Logger.getLogger(WechatController.class);
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        if (isGet) {
            return WxService.ConfigureServer(signature, timestamp, nonce, echostr);
        } else {
            // response.setHeader("Content-type", "text/xml;charset=UTF-8");
            InputStream is = request.getInputStream();
            JSONObject jmsg = Xml2Json.readFromStream(is);
            log.info("收到的消息是：" + jmsg.toJSONString());
            is.close();
            try {
                String fromUserName = (String) jmsg.get("FromUserName");
                String CreateTime = (String) jmsg.get("CreateTime");
                if (!msgMap.containsKey(fromUserName + CreateTime)) {// 去重复处理
                    msgMap.put(fromUserName + CreateTime, jmsg);
                    String handleStr = wxService.handle(jmsg);// 进行消息处理
                    // 处理结束后，删除Map中的事件
                    msgMap.remove(fromUserName + CreateTime);
                    log.info("系统回复的消息是：" + handleStr);
                }
            } catch (Exception e) {
                log.info("处理消息出问题了。。。");
                e.printStackTrace();
            }
            return "";
        }
    }

    /**
     * 微信web浏览器端，获取jssdk配置信息
     *
     * @param request
     * @param url
     * @return
     */
    @ResponseBody
    @RequestMapping("/refresh/signature")
    public ResponseEntity getWxJS_SDK(HttpServletRequest request, String url) {
        Map<String, String> sign = Sign.sign(WxConnExec.getJsapiTicket(), url);
        sign.put("appid", WxConnExec.getWechatAppid());
        return ajaxReturnMap(CODE_SUCCESS, "", sign);
    }

    /**
     * 向指定用户推送文本消息
     *
     * @param openid
     * @param msg
     * @return
     */
    @ResponseBody
    @RequestMapping("/send/txtmsg")
    public ResponseEntity sendWechatTextMsg(String openid, String msg) {
        JSONObject sendTextMsg = WxUtil.sendTextMsg(openid, msg);
        Integer errcode = sendTextMsg.getInteger("errcode");// { "errcode":0, "errmsg":"ok"}
        String errmsg = sendTextMsg.getString("errmsg");
        // JSONObject json = JSON.parseObject(sendTextMsg);
        return ajaxReturnMap(errcode, errmsg, null);
    }

//    /**
//     * 主页的入口
//     *
//     * @param code
//     * @param state
//     * @return
//     */
//    @RequestMapping("/index.cgi")
//    public String index(String code, String state) {
////        System.out.println("进入主页");
//        try {
//            Owner owner = (Owner) getSession().getAttribute(SESSION_CRN_OWNER);
//            String token = owner.getToken();
//            if (StringUtils.isEmpty(token)) {
//                return "/templates/Login/login.html?state=" + state;
//            }
//            try {
//                if (checkToken(owner.getAccount(), token)) {
//                    return "/templates/index/index.html?state=" + state;
//                }
//            } catch (TokenLoseEfficacy e1) {
//                // token过期了，清除微信和owner之间的关联
//                Owner ownerDB = ownerService.get(Owner.class, owner.getOwnerId());
//                ownerDB.setAccount("");
//                ownerDB.setBaseOwnerId("");
//                ownerDB.setToken("");
//                ownerService.saveOrUpdate(ownerDB);
//            }
//            // catch (Exception e) {//
//            // 如果在这一步出现ConnectException异常，则跳转到登陆页面。可能是token过期，也可能是后台的服务器异常
//            // logErr(e);
//            // return "/templates/Login/login.html";
//            // }
//
//            return "/templates/Login/login.html";
//
//        } catch (Exception e) {
//            logErr(e);
//            return "/err.html";
//        }
//    }


    /**
     * 获取从微信拉取到的微信用户详情
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/wxuserinfo")
    public ResponseEntity wxUserInfo() throws Exception {

        SnsapiEntity obj = (SnsapiEntity) getSession().getAttribute(SESSION_CRUN_SNSAPIENTITY);
        if (obj == null) {
            return ajaxReturnMap(CODE_SUCCESS, null, null);
        }
        Map<String, String> map = new HashMap<>();
        map.put("headimgurl", obj.getHeadimgurl());
        map.put("nickname", obj.getNickname());
        map.put("openid", obj.getOpenid());
        map.put("city", obj.getCity());
        map.put("country", obj.getCountry());
        map.put("province", obj.getProvince());
        map.put("sex", obj.getSex());
        return ajaxReturnMap(CODE_SUCCESS, "", map);
    }

}
